﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using UpdaterForm.Annotations;

namespace UpdaterForm.Tabs
{
    /// <summary>
    /// Interaction logic for AppControlNew.xaml
    /// </summary>
    public partial class AppInstance : INotifyPropertyChanged
    {
        private ObservableCollection<Update> _updates;
        public ObservableCollection<Update> Updates
        {
            get
            {
                if (_updates == null)
                    _updates = new ObservableCollection<Update>();

                return _updates;
            }
            set { _updates = value; }
        }
        
        private Update _selectedUpdate;
        public Update SelectedUpdate
        {
            get { return _selectedUpdate; }
            set
            {
                _selectedUpdate = value;
                OnPropertyChanged("SelectedUpdate");
            }
        }

        private BackgroundWorker _worker;
        private AppData _app;

        public AppInstance(AppData app)
        {
            _app = app;
            _worker = new BackgroundWorker();
            _worker.DoWork += Apply;
            _worker.RunWorkerCompleted += Complete;
            InitializeComponent();
            LoadUpdates(_app);
            
        }

        private void Complete(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                ProcessPrb.Visibility = Visibility.Collapsed;
            }));
        }

        private void Apply(object sender, DoWorkEventArgs e)
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                ProcessPrb.Visibility = Visibility.Visible;
            }));

            var updatesToInstall = new List<Update>();
            foreach (var update in Updates)
            {
                if (!StringDateCompare(update.UpdateData.Name,_app.CurrentVersion,Settings.Instance.DateFormat))
                    continue;
                

                if (update.IsInstalled > UpdateState.FullyInstalled)
                    updatesToInstall.Add(update);

                if (update.Equals(SelectedUpdate))
                    break;
            }

            if (updatesToInstall.Count > 0)
                foreach (var update in updatesToInstall)
                    update.Install();
        }

        private bool StringDateCompare(String a, string b, String format)
        {
            try
            {
                var xDate = DateTime.ParseExact(a, format, null);
                DateTime yDate;
                try
                {
                    yDate = DateTime.ParseExact(b, format, null);
                }
                catch
                {
                    yDate = DateTime.MinValue;
                }

                return xDate > yDate;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private void LoadUpdates(AppData app)
        {
            Updates.Clear();
            var updatesForldser = Settings.Instance.RepositoryPath;
            foreach (var dir in DirectoryHelper.GetDirs(new DirectoryInfo(updatesForldser)))
            {
                string appUpdate = Path.Combine(dir.FullName, app.AppName);
                if (!Directory.Exists(appUpdate))
                    continue;

                var updateDir = new DirectoryInfo(appUpdate);
                var update = new Update(updateDir, app);
                Updates.Add(update);
            }
        }

        private void ApplyBtn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (!_worker.IsBusy)
                _worker.RunWorkerAsync();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private void RefreshBtn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            LoadUpdates(_app);
        }
    }
}
